home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 163_02 / streamio.c < prev    next >
Text File  |  1988-01-30  |  6KB  |  269 lines

  1. /*
  2. ** include "streamio.c" -- standard "c" I/O routines
  3. **
  4. ** assumes _NFILE is defined
  5. ** assumes _BUFSIZE is defined
  6. ** assumes PMODE is defined
  7. ** assumes "baseio.h" is included
  8. ** assumes "baseio1.c" is included
  9. ** assumes "baseio2.c" is included
  10. ** assumes "heap.c" is included
  11. */
  12.  
  13.  
  14. static int
  15.   _iob[_IOBSIZE * _NFILE];     /* space for the iobs */
  16.  
  17.  
  18. /*
  19. ** initialize stream I/O controls
  20. */
  21.  
  22. static _strminit(namein, nameout, nameerr) char *namein, *nameout, *nameerr; {
  23.   int i, *iob;
  24.   i = 0;
  25.   iob = _iob;  /* address of file control blocks */
  26.      while(  < _NFILE) {
  27.     iob[_IOB_FLAG] = 0;        /* clear flags */
  28.     iob += _IOBSIZE;
  29.     ++i;
  30.     }
  31.   /* open stdin */
  32.   if(namein) if((stdin=fopen(namein, "r"))==NULL) exit(EIO);
  33.   /* open stdout */
  34.   if(nameout) if((stdout=fopen(nameout, "w"))==NULL) exit(EIO);
  35.   /* open stderr */
  36.   if(nameerr) if((stderr=fopen(nameerr, "r+"))==NULL) exit(EIO);
  37.   }
  38.  
  39.  
  40. /*
  41. ** clean-up stream I/O
  42. */
  43.  
  44. static _strmclnup() {
  45.   int i, *iob;
  46.   i = 0;
  47.   iob = _iob;  /* address of file control blocks */
  48.   while(i < _NFILE) {
  49.     if(iob[_IOB_FLAG] != 0) fclose(iob); /* close an open file */
  50.     iob += _IOBSIZE;
  51.     ++i;
  52.     }
  53.   }
  54.  
  55.  
  56. /*
  57. ** open a stream file
  58. */
  59.  
  60. fopen(filename, type) char *filename, *type; {
  61.   int fd, *iob, i, flag;
  62.   if(((*type!='r') && (*type!='w') && (*type!='a')) ||
  63.       ((*(type+1)!='+') && (*(type+1)!='\0'))) { /* if invalid mode */
  64.     return NULL;
  65.     }
  66.   i=0;
  67.   iob=_iob;
  68.   while(i<_NFILE) { /* find a free iob */
  69.     if((iob[_IOB_FLAG]&(~_UNBUF))==0) break;
  70.     iob+=_IOBSIZE;
  71.     ++i;
  72.     }
  73.   if(i==_NFILE) return NULL;
  74.   flag=0;
  75.   if(*(type+1)=='\0') { /* is this a normal open (vs read/write)? */
  76.     if(*type=='r') {
  77.       fd=_open(filename, 0);
  78.       flag=_READ;
  79.       }
  80.     if(*type=='w') {
  81.       fd=_creat(filename, PMODE);
  82.       flag=_WRITE;
  83.       }
  84.     if(*type=='a') {
  85.       fd=_open(filename, 1);
  86.       flag=_WRITE;
  87.       }
  88.     if(fd==-1) return NULL;
  89.     }
  90.   else { /* a read/write mode open */
  91.     if(*type == 'w') {
  92.       fd = _creat(filename, PMODE);
  93.       if(fd != -1) _close(fd);
  94.       else errno = 0; /* ignore error */
  95.       }
  96.     fd=_open(filename, 2); /* open for read/write */
  97.     if(fd == -1) return NULL;
  98.     flag = _READ|_WRITE;
  99.     }
  100.   iob[_IOB_FD]=fd;
  101.   iob[_IOB_CNT]=0;
  102.   iob[_IOB_BASE]=NULL;
  103.   iob[_IOB_SEG]=NULL;
  104.   iob[_IOB_FLAG]=0;
  105.   iob[_IOB_FLAG]|=flag;
  106.   if(_isatty(fd)) iob[_IOB_FLAG]|=_UNBUF;
  107.   if(*type == 'a') { /* if append mode, seek to end */
  108.     if(_seek(fd, -1, 2) == -1) /* backspace over ctl-Z */
  109.       errno = 0; /* ignore error */
  110.     }
  111.   return iob;
  112.   }
  113.  
  114.  
  115. /*
  116. ** close a stream file
  117. */
  118.  
  119. fclose(stream) int *stream; {
  120.   if(_chkstream(stream)) return EOF;
  121.   fflush(stream);
  122.   if(_close(stream[_IOB_FD])==-1) return EOF;
  123.   stream[_IOB_FLAG]&=_UNBUF;
  124.   return 0;
  125.   }
  126.  
  127.  
  128. /*
  129. ** flush a stream file
  130. */
  131.  
  132. fflush(stream) int *stream; {
  133.   int count;
  134.   if(_chkstream(stream)) return EOF;
  135.   if(!(stream[_IOB_FLAG]&_WRITE)) return EOF;
  136.   if((stream[_IOB_FLAG]&_DIRTY)&&(stream[_IOB_BASE])) {
  137.     count=stream[_IOB_PTR]-stream[_IOB_BASE];
  138.     _write(stream[_IOB_FD], stream[_IOB_BASE], count);
  139.     free(stream[_IOB_BASE]);
  140.     stream[_IOB_CNT]=0;
  141.     stream[_IOB_BASE]=NULL;
  142.     stream[_IOB_FLAG]&=~(_DIRTY);
  143.     }
  144.   }
  145.  
  146.  
  147. /*
  148. ** get a character from a stream file
  149. */
  150.  
  151. fgetc(stream) int *stream; {
  152.   int rcode;
  153.   char ch, *ptr;
  154.   if(_chkstream(stream)) return EOF;
  155.   if((stream==stdin)|(stream==stderr)) {
  156.     fflush(stdout);
  157.     fflush(stderr);.
  158.     }
  159.   if(stream[_IOB_FLAG]&_DIRTY) { /* if last operation was write, flush data */
  160.     fflush(stream);
  161.     }
  162.   if(stream[_IOB_FLAG]&_UNGET) { /* handle unget() character */
  163.     stream[_IOB_FLAG]&=~(_UNGET);
  164.     return (stream[_IOB_FLAG]>>8)&255;
  165.     }
  166.   if(stream[_IOB_FLAG]&_UNBUF) return _getunbuf(stream);
  167.   if(stream[_IOB_CNT]==0) {
  168.     if(stream[_IOB_BASE]=malloc(_BUFSIZE)) {
  169.       rcode=_read(stream[_IOB_FD], stream[_IOB_BASE], _BUFSIZE);
  170.       if(rcode<0) {
  171.         free(stream[_IOB_BASE]);
  172.         stream[_IOB_FLAG]|=_ERR;
  173.         return EOF;
  174.         }
  175.       if(rcode==0) {
  176.         free(stream[_IOB_BASE]);
  177.         stream[_IOB_FLAG]|=_EOF;
  178.         return EOF;
  179.         }
  180.       stream[_IOB_CNT]=rcode;
  181.       stream[_IOB_PTR]=stream[_IOB_BASE];
  182.       }
  183.     else errno = 0; /* clear malloc error */
  184.     }
  185.   if(stream[_IOB_CNT]) {
  186.     ptr=stream[_IOB_PTR]++;
  187.     ch=*ptr;
  188.     if((--stream[_IOB_CNT])==0) {
  189.       free(stream[_IOB_BASE]);
  190.       stream[_IOB_BASE]=NULL;
  191.       }
  192.     return ch&255;
  193.     }
  194.   else {
  195.     return _getunbuf(stream);
  196.     }
  197.   }
  198.  
  199.  
  200. /*
  201. ** get a character from a file -- unbuffered
  202. */
  203.  
  204. static _getunbuf(stream) int *stream; {
  205.   char ch;
  206.   int rcode;
  207.   rcode=_read(stream[_IOB_FD], &ch, 1);
  208.   if(rcode<=0) return EOF;
  209.   return ch&255;
  210.   }
  211.  
  212.  
  213. /*
  214. ** put a character to a stream file
  215. */
  216.  
  217. fputc(c, stream) char c; int *stream; {
  218.   int rcode;
  219.   char *ptr;
  220.   if(_chkstream(stream)) return EOF;
  221.   if((!(stream[_IOB_FLAG]&_DIRTY)) && (stream[_IOB_CNT])) { /* if read buff */
  222.     free(stream[_IOB_BASE]);
  223.     stream[_IOB_CNT]=0;
  224.     }
  225.   if((!stream[_IOB_CNT])&(!(stream[_IOB_FLAG]&_UNBUF))) { /* if need buffer */
  226.     if(stream[_IOB_BASE]=malloc(_BUFSIZE)) {
  227.       stream[_IOB_CNT]=_BUFSIZE;
  228.       stream[_IOB_PTR]=stream[_IOB_BASE];
  229.       stream[_IOB_FLAG]&=~(_DIRTY);
  230.       }
  231.     else errno = 0; /* clear malloc error */
  232.     }
  233.   if(stream[_IOB_CNT]) { /* if we have a buffer */
  234.     ptr=stream[_IOB_PTR]++;
  235.     *ptr=c;
  236.     if(!(--stream[_IOB_CNT])) { /* if buffer is full */
  237.       rcode=_write(stream[_IOB_FD], stream[_IOB_BASE], _BUFSIZE);
  238.       free(stream[_IOB_BASE]);
  239.       stream[_IOB_BASE]=NULL;
  240.       stream[_IOB_FLAG] &= ~(_DIRTY);
  241.       if(rcode== -1) return EOF;
  242.       }
  243.     else{
  244.       stream[_IOB_FLAG] |= _DIRTY;
  245.       }
  246.     }
  247.   else { /* no buffer */
  248.     rcode=_write(stream[_IOB_FD], &c, 1);
  249.     if(rcode== -1) return EOF;
  250.     }
  251.   return c&255;
  252.   }
  253.  
  254.  
  255. /*
  256. ** assure that the stream pointer is valid
  257. */
  258.  
  259. static _chkstream(stream) int *stream; {
  260.   int i, *iob;
  261.   iob=_iob;
  262.   i=0;
  263.   while(i++<_NFILE) {
  264.     if(stream==iob) return 0; /* ok */
  265.     iob+=_IOBSIZE;
  266.     }
  267.   return 1; /* not an iob address */
  268.   }
  269.